const express = require("express");
const { Registration, Command, WinexDataCleanCommand, WinexDataGenerationCommand, ExecuteJmxCommand } = require("../remoteMachine");
const { Execution: ExecutionDb, ExecutionResult, Command: CommandDb } = require("../db");

const router = express.Router();

router.post("/platform/getRemoteMachines", async (req, res) => {
    try {
        const registration = new Registration();
        let remoteMachines = await registration.getRemoteMachines();
        const response = remoteMachines;
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

router.post("/platform/cleanRemoteMachines", async (req, res) => {
    try {
        const { isForced } = req.body;
        const registration = new Registration();
        await registration.clean(isForced);
        const response = {};
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

router.post("/machine/heartbeat", async (req, res) => {
    try {
        let { machineUuid, machineName, machineStatus } = req.body;
        const registration = new Registration();
        machineUuid = await registration.register(machineUuid, machineName, machineStatus);
        let response = null;
        if (machineStatus === "idle") {
            let command = new Command(machineUuid);
            command = await command.pop();
            response = command;
        }
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

router.post("/machine/executeJmx", async (req, res) => {
    try {
        let { machineUuid, jmxUuid, testPlans, duration, maxRound } = req.body;
        if (!(machineUuid && jmxUuid && testPlans && duration && maxRound)) {
            res.customResponse(300, "参数不能为空", {});
            return;
        }
        const command = new ExecuteJmxCommand(machineUuid, jmxUuid, testPlans, duration, maxRound);
        await command.push()
        const registration = new Registration();
        const remoteMachine = await registration.getRemoteMachine(machineUuid);
        const machineName = remoteMachine && remoteMachine.machineName;
        if (!machineName) {
            res.customResponse(300, "机器未注册", {});
            return;
        }
        await ExecutionDb.create({
            uuid: command.commandUuid,
            jmx_uuid: jmxUuid,
            machine_uuid: machineUuid,
            machine_name: machineName,
            status: 0
        });
        await CommandDb.create({
            uuid: command.commandUuid,
            command_type: "executeJmx",
            machine_uuid: machineUuid,
            machine_name: machineName,
            machine_location: "",
            status: 0
        });
        let response = { uuid: command.commandUuid };
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

router.post("/machine/winex/cleanData", async (req, res) => {
    try {
        let { machineUuid } = req.body;
        const command = new WinexDataCleanCommand(machineUuid);
        await command.push();
        await CommandDb.create({
            uuid: command.commandUuid,
            command_type: "winexDataClean",
            machine_uuid: machineUuid,
            machine_name: "",
            machine_location: "",
            status: 0
        });
        let response = { uuid: command.commandUuid };
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

router.post("/machine/winex/generateData", async (req, res) => {
    try {
        let { machineUuid, loginUrl, adminLoginData, hisLoginData, outpatientDoctorLoginData, inpatientDoctorLoginData, inpatientNurseLoginData } = req.body;
        const command = new WinexDataGenerationCommand(machineUuid, loginUrl, adminLoginData, hisLoginData, outpatientDoctorLoginData, inpatientDoctorLoginData, inpatientNurseLoginData);
        await command.push();
        await CommandDb.create({
            uuid: command.commandUuid,
            command_type: "winexDataGeneration",
            machine_uuid: machineUuid,
            machine_name: "",
            machine_location: "",
            status: 0
        });
        let response = { uuid: command.commandUuid };
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

router.post("/platform/command/updateStatus", async (req, res) => {
    try {
        let { commandUuid, status } = req.body;
        await CommandDb.update({ status: status }, { where: { uuid: commandUuid } });
        let response = { commandUuid, status };
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

router.post("/platform/exection/updateStatus", async (req, res) => {
    try {
        let { exectionUuid, status } = req.body;
        await ExecutionDb.update({ status: status }, { where: { uuid: exectionUuid } });
        let response = { commandUuid: exectionUuid, status };
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

router.post("/machine/report", async (req, res) => {
    try {
        /** @type {{uuid: string, testResults: object[][]}} */
        let { uuid, testResults } = req.body;
        for (let i = 0; i < testResults.length; i++) {
            const testResult = testResults[i];
            for (let j = 0; j < testResult.length; j++) {
                const roundNumber = i;
                const testPlanName = testResult[j].testPlanName;
                await ExecutionResult.create({
                    uuid: uuid,
                    round_num: roundNumber,
                    test_plan_name: testPlanName,
                    result: JSON.stringify(testResult[j])
                });
            }
        }
        ExecutionDb.update({ status: 2 }, { where: { uuid: uuid } });
        const response = {};
        res.customResponse(200, "success", response);
    } catch (error) {
        console.log(error);
        res.customResponse(500, error.message, {});
    }
});

module.exports = router;
